#pragma once

#include <memory>

/// dll导入
#ifdef DEF_PLATFORM_WINDOWS
#ifdef DEF_DYNAMIC_LINK
	#ifdef DEF_DLL_EXPORT
		#define HZ_DLL_OPTION _declspec(dllexport)
	#else
		#define HZ_DLL_OPTION _declspec(dllimport)
	#endif
#else
	#define HZ_DLL_OPTION
#endif
#else
	#error Hazal only support on Windows
#endif

#ifdef DEF_ENABLE_ASSERTS
	#define HZ_ASSERT(x, ...) { if(!(x)) { LOG_ERROR("Assertion Failed: {0}", __VA_ARGS__); __debugbreak; } }
	#define HZ_CORE_ASSERT(x, ...) { if(!(x)) { LOG_CORE_ERROR("Assertion Core Failed: {0}", __VA_ARGS__); __debugbreak; } }
#else
	#define HZ_ASSERT(x, info)
	#define HZ_CORE_ASSERT(x, info)
#endif

#define BIT(x) (1 << x)

#define HZ_BIND_EVENT_FN(fn) std::bind(&fn, this, std::placeholders::_1)

namespace Hazal
{
	template<typename T>
	using Scope = std::unique_ptr<T>;
	
	template<typename T, typename ... Args>
	constexpr Scope<T> CreateScope(Args&& ... args)
	{
		return std::make_unique<T>(std::forward<Args>(args)...);
	}

	template<typename T>
	using Ref = std::shared_ptr<T>;

	template<typename T, typename ... Args>
	constexpr Ref<T> CreateRef(Args&& ... args)
	{
		return std::make_shared<T>(std::forward<Args>(args)...);
	}
}